package net.openvision.music.composition.logical.parsing;

import java.io.IOException;
import java.io.Reader;
import java.text.ParseException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.openvision.util.logical.LogicalExpression;
import net.openvision.util.logical.LogicalPredicate;
import net.openvision.util.logical.Predicate;

public class TextPredicateParser implements PredicateParser {

	public static final String AND = "AND";
	public static final String OR = "OR";
	public static final String IMPLIES = "->";
	public static final String IFF = "<->";
	public static final String NOT = "NOT";
	public static final String EXISTS = "EXISTS";
	public static final String FORALL = "ALL";
	public static final String OPEN_BRACE = "(";
	public static final String CLOSE_BRACE = ")";
	
	private String andExp = "\\((.*)\\)\\s*" + AND + "\\s*\\((.*)\\)";

	private LogicalExpression parseLogicalExpression(String str) {
		
		return null;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Predicate parse(Reader reader) throws IOException, ParseException,
			IllegalAccessException, InstantiationException {
		StringBuilder sb = new StringBuilder();
		int ch = reader.read();
		while (ch >= 0) {
			sb.append((char) ch);
			ch = reader.read();
		}
		Pattern p = Pattern
				.compile("(.*)\\[\\s*(\\w*(\\s*,\\s*\\w*)*\\s*)\\]\\s*:=(.*)");
		Matcher m = p.matcher(sb.toString());

		if (!m.matches())
			throw new ParseException("Syntax exception.", -1);
		for (int i = 0; i < m.groupCount() + 1; i++) {
			System.out.println("GROUP " + i + " = " + m.group(i));
		}
		String name = m.group(1).trim();
		System.out.println("NAME = " + name);
		String[] params = m.group(2).split(",");
		for (int i = 0; i < params.length; i++) {
			System.out.println("PARAM[" + i + "] = " + params[i].trim());
		}
		String body = m.group(4).trim();
		System.out.println("BODY = " + body);

		try {
			Class<? extends Predicate> clazz = (Class<? extends Predicate>) Class
					.forName(body);
			return clazz.newInstance();
		} catch (ClassNotFoundException c) {
			return new LogicalPredicate(parseLogicalExpression(body));
		}
	}

}
